/*
 * @Author: wuqingchun
 * @Date: 2024-04-28 15:25:58
 * @Description: lambda 表达式使用
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-04-28 15:59:48
 */

#include <iostream>

/**
 * @brief 隐式值捕获
 * 
 */
void test_implicit_value_capture(int arg)
{
    int a = 100;
    int b = 200;

    std::cout << __FUNCTION__ << std::endl;

    auto myFunc = [=]  (int c, int d) -> int {
        // : error: assignment of read-only variable ‘a’，编译报错
        // a = c + d;
        // b = c - d;

        std::cout << __FUNCTION__ << ",lambda inner, arg: " << arg << std::endl;
        std::cout << __FUNCTION__ << ",lambda inner, a: " << a << std::endl;
        std::cout << __FUNCTION__ << ",lambda inner, b: " << b << std::endl;

        return a + b + c + d;
    };

    a = 1000;
    b = 2000;

    std::cout << "call before, a: " << a << std::endl;
    std::cout << "call before, b: " << b << std::endl;

    int result = myFunc(300, 400);

    std::cout << "call after, a: " << a << std::endl;
    std::cout << "call after, b: " << b << std::endl;

    std::cout << "result: " << result << std::endl;
}

void test_implicit_value_capture_mutable(int arg)
{
    int a = 100;
    int b = 200;

    std::cout << __FUNCTION__ << std::endl;

    auto myFunc = [=]  (int c, int d) mutable-> int {
        std::cout << __FUNCTION__ << ",lambda inner, arg: " << arg << std::endl;
        std::cout << __FUNCTION__ << ",lambda inner, a: " << a << std::endl;
        std::cout << __FUNCTION__ << ",lambda inner, b: " << b << std::endl;

        a = c + d;
        b = c - d;

        return a + b + c + d;
    };

    a = 1000;
    b = 2000;

    std::cout << "call before, a: " << a << std::endl;
    std::cout << "call before, b: " << b << std::endl;

    int result = myFunc(300, 400);

    std::cout << "call after, a: " << a << std::endl;
    std::cout << "call after, b: " << b << std::endl;

    std::cout << "result: " << result << std::endl;
}

/**
 * @brief 隐式引用捕获
 * 
 */
void test_implicit_reference_capture()
{
    int a = 100;
    int b = 200;

    std::cout << __FUNCTION__ << std::endl;

    auto myFunc = [&]  (int c, int d) -> int {

        std::cout << __FUNCTION__ << ",lambda inner, a: " << a << std::endl;
        std::cout << __FUNCTION__ << ",lambda inner, b: " << b << std::endl;

        a = c + d;
        b = c - d;
        
        return a + b + c + d;
    };

    a = 111;

    std::cout << "call before, a: " << a << std::endl;
    std::cout << "call before, b: " << b << std::endl;

    int result = myFunc(300, 400);

    std::cout << "call after, a: " << a << std::endl;
    std::cout << "call after, b: " << b << std::endl;

    std::cout << "result: " << result << std::endl;
}


/**
 * @brief 显式绑定
 * 
 * @param arg 
 */
void test_explicit_value_capture_mutable(int arg)
{
    int a = 100;
    int b = 200;

    std::cout << __FUNCTION__ << std::endl;

    auto myFunc = [&a, b, arg]  (int c, int d) -> int {
        std::cout << __FUNCTION__ << ",lambda inner, arg: " << arg << std::endl;
        std::cout << __FUNCTION__ << ",lambda inner, a: " << a << std::endl;
        std::cout << __FUNCTION__ << ",lambda inner, b: " << b << std::endl;

        a = c + d;
        // b = c - d;
        return a + b + c + d;
    };

    a = 1000;
    b = 2000;

    std::cout << "call before, a: " << a << std::endl;
    std::cout << "call before, b: " << b << std::endl;

    int result = myFunc(300, 400);

    std::cout << "call after, a: " << a << std::endl;
    std::cout << "call after, b: " << b << std::endl;

    std::cout << "result: " << result << std::endl;
}

int main()
{
    test_implicit_value_capture(111);
    std::cout << std::endl;
    test_implicit_value_capture_mutable(22);
    std::cout << std::endl;
    test_implicit_reference_capture();

    std::cout << std::endl;
    test_explicit_value_capture_mutable(333);

    return 0;
}